---
type: tutorial
title: Construa uma página de Índice de Tags
description: |-
  Tutorial: Construa seu primeiro blog Astro —
  Use tudo o que você aprendeu até agora para criar uma página de índice de tags
i18nReady: true
---
import Box from '~/components/tutorial/Box.astro';
import Checklist from '~/components/Checklist.astro';
import MultipleChoice from '~/components/tutorial/MultipleChoice.astro';
import Option from '~/components/tutorial/Option.astro';
import PreCheck from '~/components/tutorial/PreCheck.astro';
import { Steps } from '@astrojs/starlight/components';

Agora que você tem páginas individuais para cada tag, é hora de fazer links para elas.

<PreCheck>
  - Adicionar uma nova página utilizando o padrão de roteamento `/pages/pasta/index.astro`
  - Mostrar uma lista de todas as suas tags únicas, fazendo links para cada página de tag
  - Atualizar seu site com links de navegação para essa nova página Tags
</PreCheck>

## Utilize o padrão de roteamento `/pages/pasta/index.astro`

Para adicionar uma página Índice de Tags ao seu website, você poderia criar um novo arquivo em `src/pages/tags.astro`. 

Porém, já que você já tem o diretório `/tags/`, você pode se aproveitar de outro padrão de roteamento no Astro, e manter todos os seus arquivos relacionados à tags juntos.

<Box icon="puzzle-piece">

## Tente você mesmo - Faça uma página de Índice de Tags

<Steps>
1. Crie um novo arquivo `index.astro` no diretório `src/pages/tags/`.

2. Navegue para `http://localhost:4321/tags` e verifique que seu site agora contém uma página nessa URL. Ela estará vazia, mas vai existir.

3. Crie uma página mínima em `src/pages/tags/index.astro` que utiliza seu layout. Você já fez isso anteriormente!

    <details>
      <summary>Expanda para ver as etapas</summary>
      <Steps>
      1. Crie um novo componente de página em `src/pages/tags/`.

          <details>
          <summary>Mostre o nome do arquivo</summary>
          ```
          index.astro
          ```
          </details>

      2. Importe e utilize seu `<BaseLayout>`.

          <details>
          <summary>Mostre o código</summary>
          ```astro title=" src/pages/tags/index.astro"
          ---
          import BaseLayout from '../../layouts/BaseLayout.astro';
          ---
          <BaseLayout></BaseLayout>
          ```
          </details>

      3. Defina um título da página, e passe-o para o seu layout como um atributo do componente.

          <details>
          <summary>Mostre o código</summary>
          ```astro title="src/pages/tags/index.astro" ins={3} "pageTitle"
          ---
          import BaseLayout from '../../layouts/BaseLayout.astro';
          const pageTitle = "Índice de Tags";
          ---
          <BaseLayout pageTitle={pageTitle}></BaseLayout>
          ```
          </details>
      </Steps>
    </details>

4. Verifique sua pré-visualização do navegador novamente e você deve ter uma página formatada, pronta para adicionar conteúdo nela!
</Steps>
</Box>

## Crie um array de tags

Você havia anteriormente mostrado itens em uma lista de um array utilizando `map()`. Como se pareceria definir um array de todas as suas tags, e então mostrá-las em uma lista nessa página?

<details>
    <summary>Veja o código</summary>
    
    ```astro title="src/pages/tags/index.astro"
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const tags = ['astro', 'blogar', 'aprender em público', 'sucessos', 'contratempos', 'comunidade'];
    const pageTitle = "Índice de Tags";
    ---
    <BaseLayout pageTitle={pageTitle}>
      <ul>
        {tags.map((tag) => <li>{tag}</li>)}
      </ul>
    </BaseLayout>
    ```
</details>

Você poderia fazer isso, mas então você teria que voltar para esse arquivo e atualizar seu array toda vez que você utiliza uma nova tag em uma futura postagem no blog.

Felizmente, você já sabe uma forma de conseguir os dados de todos os seus arquivos Markdown em uma linha de código, e então retornar uma lista de todas as suas tags.

<Steps>
1. Em `src/pages/tags/index.astro`, adicione a linha de código para o script frontmatter que irá dar à sua página acesso aos dados de todo arquivo `.md` de postagem do blog.

    <details>
    <summary>Veja o código</summary>
    ```astro title = "src/pages/tags/index.astro" ins={3}
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const pageTitle = "Índice de Tags";
    ---
    ```
    </details>

2. Depois, adicione a seguinte linha de JavaScript ao seu componente da página. Essa é a mesma linha que você utilizou em `src/pages/tags/[tag].astro` para retornar uma lista de tags únicas.

    ```astro title = "src/pages/tags/index.astro" ins={4}
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
    const pageTitle = "Índice de Tags";
    ---
    
    ```
</Steps>

## Crie sua lista de tags

Ao invés de criar items em uma lista desordenada dessa vez, crie um `<p>` para cada item, dentro de `<div>`. O padrão deve parecer familiar!

<Steps>
1. Adicione o seguinte código para seu template do componente:

    ```astro title="src/pages/tags/index.astro" ins={2}
    <BaseLayout pageTitle={pageTitle}>
      <div>{tags.map((tag) => <p>{tag}</p>)}</div>
    </BaseLayout>
    ```
    Na sua pré-visualização do navegador, verifique que você pode ver suas tags listadas.

2. Para fazer cada tag ter um link para sua própria página, adicione o seguinte link `<a>` para cada nome de tag:

    ```astro title="src/pages/tags/index.astro" '/tags/${tag}'
    <BaseLayout pageTitle={pageTitle}>
      <div>
        {tags.map((tag) => (
          <p><a href={`/tags/${tag}`}>{tag}</a></p>
        ))}
      </div>
    </BaseLayout>
    ```
</Steps>

## Adicione estilos a sua lista de tags

<Steps>
1. Adicione as seguintes classes CSS para estilizar tanto sua `<div>` quanto cada `<p>` que será gerado. Nota: Astro utiliza a sintaxe do HTML para adicionar nomes de classes!

    ```astro title="src/pages/tags/index.astro" 'class="tags"' 'class="tag"'
    <BaseLayout pageTitle={pageTitle}>
      <div class="tags">
        {tags.map((tag) => (
          <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
        ))}
      </div>
    </BaseLayout>
    ```

2. Defina essas novas classes CSS adicionando a seguinte tag `<style>` para essa página:

    ```astro title="src/pages/tags/index.astro"
    <style>
      a {
        color: #00539F;
      }

      .tags {
        display: flex; 
        flex-wrap: wrap; 
      }

      .tag {
        margin: 0.25em;
        border: dotted 1px #a1a1a1;
        border-radius: .5em;
        padding: .5em 1em;
        font-size: 1.15em;
        background-color: #F8FCFD;
      }
    </style>
    ```

3. Cheque a pré-visualização do seu navegador em `http://localhost:4321/tags` para verificar que você tem uns novos estilos e que cada uma das tags na página tem um link funcional para sua própria página de tag individual.
</Steps>

### Check In de Código

Aqui está como sua nova página deve se parecer:

```astro title="src/pages/tags/index.astro"
--- 
import BaseLayout from '../../layouts/BaseLayout.astro';
const allPosts = await Astro.glob('../posts/*.md');
const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
const pageTitle = "Índice de Tags";
---
<BaseLayout pageTitle={pageTitle}>
  <div class="tags">
    {tags.map((tag) => (
      <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
  </div>
</BaseLayout>
<style>
  a {
    color: #00539F;
  }

  .tags {
    display: flex; 
    flex-wrap: wrap; 
  }

  .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
  }
</style>
```

## Adicione essa página à sua navegação

Neste momento, você pode navegar para `http://localhost:4321/tags` e ver essa página. A partir dessa página, você pode clicar em links para suas páginas individuais de tags.

Porém, você ainda precisa fazer com que essas páginas possam ser encontradas a partir de outras páginas no seu website.

<Steps>
1. Em seu componente `Navigation.astro`, inclua um link para essa nova página Índice de Tags.

    <details>
    <summary>Me mostre o código</summary>
    ```astro title="src/components/Navegacao.astro" ins={4}
    <a href="/">Início</a>
    <a href="/about/">Sobre</a>
    <a href="/blog/">Blog</a>
    <a href="/tags/">Tags</a>
    ```
    </details>
</Steps>

<Box icon="puzzle-piece">

## Desafio: Inclua tags em seu layout de postagem do blog

Agora você escreveu todo o código que você precisa para também mostrar uma lista de tags em cada postagem do blog, e fazer links para suas páginas de tag. Você tem trabalho existente que pode reutilizar!

Siga as etapas abaixo, e então cheque seu trabalho o comparando com a [amostra de código final](#check-in-de-código-markdownpostlayout).
<Steps>

1. Copie `<div class="tags">...</div>` e `<style>...</style>` de `src/pages/tags/index.astro` e o reutilize dentro de `MarkdownPostLayout.astro`:

    ```astro title="src/layouts/MarkdownPostLayout.astro" ins={13-17, 21-40}
    ---
    import BaseLayout from './BaseLayout.astro';
    const { frontmatter } = Astro.props;
    --- 
    <BaseLayout pageTitle={frontmatter.title}>
      <p><em>{frontmatter.description}</em></p>
      <p>{frontmatter.pubDate.toString().slice(0,10)}</p>

      <p>Escrito por: {frontmatter.author}</p>

      <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />

      <div class="tags">
        {tags.map((tag) => (
          <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
        ))}
      </div>

      <slot />
    </BaseLayout>
    <style>
      a {
        color: #00539F;
      }

      .tags {
        display: flex; 
        flex-wrap: wrap; 
      }

      .tag {
        margin: 0.25em;
        border: dotted 1px #a1a1a1;
        border-radius: .5em;
        padding: .5em 1em;
        font-size: 1.15em;
        background-color: #F8FCFD;
      }
    </style>
    ```

</Steps>

Antes desse código funcionar, você precisa fazer **uma pequena modificação** no código que você colou em `MarkdownPostLayout.astro`. Você consegue descobrir qual é a modificação?

<details>
<summary>Me dê uma dica</summary>

Como estão as outras props (e.x. title, author, etc.) escritas no template do seu layout? Como seu layout recebe props de uma postagem individual do blog?
</details>

<details>
<summary>Me dê outra dica!</summary>

Para que se utilize props (valores passados) de uma postagem do blog `.md` em seu layout, como tags, você precisa prefixar o valor com uma certa palavra.
<details>
<summary>Me mostre o código!</summary>

```astro title="src/layouts/MarkdownPostLayout.astro" "frontmatter"
    <div class="tags">
      {frontmatter.tags.map((tag) => (
        <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
      ))}
    </div>
```
</details>
</details>
</Box>

### Check In de Código: MarkdownPostLayout

Para verificar seu trabalho, ou se você só quer o código completo e correto para copiar em `MarkdownPostLayout.astro`, aqui está como seu componente Astro deve se parecer como:

```astro title="src/layouts/MarkdownPostLayout.astro"
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
--- 
<BaseLayout pageTitle={frontmatter.title}>
  <p><em>{frontmatter.description}</em></p>
  <p>{frontmatter.pubDate.toString().slice(0,10)}</p>

  <p>Escrito por: {frontmatter.author}</p>

  <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} /> 

  <div class="tags">
    {frontmatter.tags.map((tag) => (
      <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
  </div>

  <slot />
</BaseLayout>
<style>
  a {
    color: #00539F;
  }

  .tags {
    display: flex; 
    flex-wrap: wrap; 
  }

  .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
  }
</style>
```



<Box icon="question-mark">

### Teste seu conhecimento

Corresponda cada caminho de arquivo com um segundo caminho de arquivo que irá criar uma página na mesma rota.

1. `src/pages/categorias.astro`

    <MultipleChoice>
      <Option>`src/pages/posts/post.astro`</Option>
      <Option>`src/pages/posts/index.astro`</Option>
      <Option>`src/components/sapatos/sapato.astro`</Option>
      <Option isCorrect>`src/pages/categorias/index.astro`</Option>
    </MultipleChoice>

2. `src/pages/posts.astro`

    <MultipleChoice>
      <Option>`src/pages/products/sapatos.astro`</Option>
      <Option>`src/pages/posts/post.astro`</Option>
      <Option isCorrect>`src/pages/posts/index.astro`</Option>
      <Option>`src/pages/categorias/index.astro`</Option>
    </MultipleChoice>

3. `src/pages/products/sapatos/index.astro`

    <MultipleChoice>
      <Option isCorrect>`src/pages/products/sapatos.astro`</Option>
      <Option>`src/pages/posts/post.astro`</Option>
      <Option>`src/pages/posts/index.astro`</Option>
      <Option>`src/components/sapatos/sapato.astro`</Option>
    </MultipleChoice>

</Box>

<Box icon="check-list">

## Checklist

<Checklist>
- [ ] Eu posso utilizar a funcionalidade de padrão de roteamento `/pages/pasta/index.astro`.
</Checklist>
</Box>

### Recursos

- [Roteamento Estático no Astro](/pt-br/guides/routing/#static-routes)
